package cc.rengu.igas.share.facade.bean.cups;

import cc.rengu.oltp.service.common.enums.OltpRpcdEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.utility.util.StringUtil;
import cc.rengu.utility.log.RgLog;
import cc.rengu.utility.log.RgLogger;

/**
 * 银联8583报文57域附加交易信息
 *
 * @author fangminwei
 * @date 2021/4/16
 */
@SuppressWarnings("AlibabaLowerCamelCaseVariableNaming")
public class F57 {
    /****************  用法AB：公共支付信息 *********************/
    private String f57_AB_1;
    private String f57_AB_2;
    private String f57_AB_3;

    /****************  用法IP：分期付款信息 *********************/
    private String f57_IP_1;
    private String f57_IP_2;
    private String f57_IP_3;
    private String f57_IP_4;
    private String f57_IP_5;
    private String f57_IP_6_1;
    private String f57_IP_6_2;
    private String f57_IP_6_3;
    private String f57_IP_6_4;
    private String f57_IP_6_5;

    /****************  用法CI：持卡人身份信息 *********************/
    private String f57_CI_1;
    private String f57_CI_2;
    private String f57_CI_3;
    private String f57_CI_4;
    private String f57_CI_5;

    /****************  用法RP：积分兑换信息 *********************/
    private String f57_RP_1;
    private String f57_RP_2;
    private String f57_RP_3;
    private String f57_RP_4;

    /*###############  用法AS：组合用法 ###############*/
    /**
     * 公共支付信息（AB）
     */
    private String f57_AS_AB_1;
    private String f57_AS_AB_2;
    private String f57_AS_AB_3;

    /**
     * 分期付款信息（IP）
     */
    private String f57_AS_IP_1;
    private String f57_AS_IP_2;
    private String f57_AS_IP_3;
    private String f57_AS_IP_4;
    private String f57_AS_IP_5_1;
    private String f57_AS_IP_5_2;
    private String f57_AS_IP_5_3;
    private String f57_AS_IP_5_4;
    private String f57_AS_IP_5_5;

    /**
     * 持卡人身份信息（CI）
     */
    private String f57_AS_CI_1;
    private String f57_AS_CI_2;
    private String f57_AS_CI_3;
    private String f57_AS_CI_4;

    /**
     * 积分兑换信息（RP）
     */
    private String f57_AS_RP_1;
    private String f57_AS_RP_2;
    private String f57_AS_RP_3;

    /**
     * 折扣消费交易中的刷卡金额（RA）
     */
    private String f57_AS_RA_1;

    /**
     * 下次可充值金额（NA）
     */
    private String f57_AS_NA_1;

    /**
     * 转入卡所属地信息（IA）
     */
    private String f57_AS_IA_1;

    /**
     * 无卡自助消费业务开通信息（SE）
     */
    private String f57_AS_SE_1;
    private String f57_AS_SE_2;
    private String f57_AS_SE_3;

    /**
     * 附加应答码信息(AR)
     */
    private String f57_AS_AR_1;
    private String f57_AS_AR_2;

    /**
     * 保留使用（ID）
     */
    private String f57_AS_ID;

    public String getF57_AB_1() {
        return f57_AB_1;
    }

    public void setF57_AB_1(String f57_AB_1) {
        this.f57_AB_1 = f57_AB_1;
    }

    public String getF57_AB_2() {
        return f57_AB_2;
    }

    public void setF57_AB_2(String f57_AB_2) {
        this.f57_AB_2 = f57_AB_2;
    }

    public String getF57_AB_3() {
        return f57_AB_3;
    }

    public void setF57_AB_3(String f57_AB_3) {
        this.f57_AB_3 = f57_AB_3;
    }

    public String getF57_IP_1() {
        return f57_IP_1;
    }

    public void setF57_IP_1(String f57_IP_1) {
        this.f57_IP_1 = f57_IP_1;
    }

    public String getF57_IP_2() {
        return f57_IP_2;
    }

    public void setF57_IP_2(String f57_IP_2) {
        this.f57_IP_2 = f57_IP_2;
    }

    public String getF57_IP_3() {
        return f57_IP_3;
    }

    public void setF57_IP_3(String f57_IP_3) {
        this.f57_IP_3 = f57_IP_3;
    }

    public String getF57_IP_4() {
        return f57_IP_4;
    }

    public void setF57_IP_4(String f57_IP_4) {
        this.f57_IP_4 = f57_IP_4;
    }

    public String getF57_IP_5() {
        return f57_IP_5;
    }

    public void setF57_IP_5(String f57_IP_5) {
        this.f57_IP_5 = f57_IP_5;
    }

    public String getF57_IP_6_1() {
        return f57_IP_6_1;
    }

    public void setF57_IP_6_1(String f57_IP_6_1) {
        this.f57_IP_6_1 = f57_IP_6_1;
    }

    public String getF57_IP_6_2() {
        return f57_IP_6_2;
    }

    public void setF57_IP_6_2(String f57_IP_6_2) {
        this.f57_IP_6_2 = f57_IP_6_2;
    }

    public String getF57_IP_6_3() {
        return f57_IP_6_3;
    }

    public void setF57_IP_6_3(String f57_IP_6_3) {
        this.f57_IP_6_3 = f57_IP_6_3;
    }

    public String getF57_IP_6_4() {
        return f57_IP_6_4;
    }

    public void setF57_IP_6_4(String f57_IP_6_4) {
        this.f57_IP_6_4 = f57_IP_6_4;
    }

    public String getF57_IP_6_5() {
        return f57_IP_6_5;
    }

    public void setF57_IP_6_5(String f57_IP_6_5) {
        this.f57_IP_6_5 = f57_IP_6_5;
    }

    public String getF57_CI_1() {
        return f57_CI_1;
    }

    public void setF57_CI_1(String f57_CI_1) {
        this.f57_CI_1 = f57_CI_1;
    }

    public String getF57_CI_2() {
        return f57_CI_2;
    }

    public void setF57_CI_2(String f57_CI_2) {
        this.f57_CI_2 = f57_CI_2;
    }

    public String getF57_CI_3() {
        return f57_CI_3;
    }

    public void setF57_CI_3(String f57_CI_3) {
        this.f57_CI_3 = f57_CI_3;
    }

    public String getF57_CI_4() {
        return f57_CI_4;
    }

    public void setF57_CI_4(String f57_CI_4) {
        this.f57_CI_4 = f57_CI_4;
    }

    public String getF57_CI_5() {
        return f57_CI_5;
    }

    public void setF57_CI_5(String f57_CI_5) {
        this.f57_CI_5 = f57_CI_5;
    }

    public String getF57_RP_1() {
        return f57_RP_1;
    }

    public void setF57_RP_1(String f57_RP_1) {
        this.f57_RP_1 = f57_RP_1;
    }

    public String getF57_RP_2() {
        return f57_RP_2;
    }

    public void setF57_RP_2(String f57_RP_2) {
        this.f57_RP_2 = f57_RP_2;
    }

    public String getF57_RP_3() {
        return f57_RP_3;
    }

    public void setF57_RP_3(String f57_RP_3) {
        this.f57_RP_3 = f57_RP_3;
    }

    public String getF57_RP_4() {
        return f57_RP_4;
    }

    public void setF57_RP_4(String f57_RP_4) {
        this.f57_RP_4 = f57_RP_4;
    }

    public String getF57_AS_AB_1() {
        return f57_AS_AB_1;
    }

    public void setF57_AS_AB_1(String f57_AS_AB_1) {
        this.f57_AS_AB_1 = f57_AS_AB_1;
    }

    public String getF57_AS_AB_2() {
        return f57_AS_AB_2;
    }

    public void setF57_AS_AB_2(String f57_AS_AB_2) {
        this.f57_AS_AB_2 = f57_AS_AB_2;
    }

    public String getF57_AS_AB_3() {
        return f57_AS_AB_3;
    }

    public void setF57_AS_AB_3(String f57_AS_AB_3) {
        this.f57_AS_AB_3 = f57_AS_AB_3;
    }

    public String getF57_AS_IP_1() {
        return f57_AS_IP_1;
    }

    public void setF57_AS_IP_1(String f57_AS_IP_1) {
        this.f57_AS_IP_1 = f57_AS_IP_1;
    }

    public String getF57_AS_IP_2() {
        return f57_AS_IP_2;
    }

    public void setF57_AS_IP_2(String f57_AS_IP_2) {
        this.f57_AS_IP_2 = f57_AS_IP_2;
    }

    public String getF57_AS_IP_3() {
        return f57_AS_IP_3;
    }

    public void setF57_AS_IP_3(String f57_AS_IP_3) {
        this.f57_AS_IP_3 = f57_AS_IP_3;
    }

    public String getF57_AS_IP_4() {
        return f57_AS_IP_4;
    }

    public void setF57_AS_IP_4(String f57_AS_IP_4) {
        this.f57_AS_IP_4 = f57_AS_IP_4;
    }

    public String getF57_AS_IP_5_1() {
        return f57_AS_IP_5_1;
    }

    public void setF57_AS_IP_5_1(String f57_AS_IP_5_1) {
        this.f57_AS_IP_5_1 = f57_AS_IP_5_1;
    }

    public String getF57_AS_IP_5_2() {
        return f57_AS_IP_5_2;
    }

    public void setF57_AS_IP_5_2(String f57_AS_IP_5_2) {
        this.f57_AS_IP_5_2 = f57_AS_IP_5_2;
    }

    public String getF57_AS_IP_5_3() {
        return f57_AS_IP_5_3;
    }

    public void setF57_AS_IP_5_3(String f57_AS_IP_5_3) {
        this.f57_AS_IP_5_3 = f57_AS_IP_5_3;
    }

    public String getF57_AS_IP_5_4() {
        return f57_AS_IP_5_4;
    }

    public void setF57_AS_IP_5_4(String f57_AS_IP_5_4) {
        this.f57_AS_IP_5_4 = f57_AS_IP_5_4;
    }

    public String getF57_AS_IP_5_5() {
        return f57_AS_IP_5_5;
    }

    public void setF57_AS_IP_5_5(String f57_AS_IP_5_5) {
        this.f57_AS_IP_5_5 = f57_AS_IP_5_5;
    }

    public String getF57_AS_CI_1() {
        return f57_AS_CI_1;
    }

    public void setF57_AS_CI_1(String f57_AS_CI_1) {
        this.f57_AS_CI_1 = f57_AS_CI_1;
    }

    public String getF57_AS_CI_2() {
        return f57_AS_CI_2;
    }

    public void setF57_AS_CI_2(String f57_AS_CI_2) {
        this.f57_AS_CI_2 = f57_AS_CI_2;
    }

    public String getF57_AS_CI_3() {
        return f57_AS_CI_3;
    }

    public void setF57_AS_CI_3(String f57_AS_CI_3) {
        this.f57_AS_CI_3 = f57_AS_CI_3;
    }

    public String getF57_AS_CI_4() {
        return f57_AS_CI_4;
    }

    public void setF57_AS_CI_4(String f57_AS_CI_4) {
        this.f57_AS_CI_4 = f57_AS_CI_4;
    }

    public String getF57_AS_RP_1() {
        return f57_AS_RP_1;
    }

    public void setF57_AS_RP_1(String f57_AS_RP_1) {
        this.f57_AS_RP_1 = f57_AS_RP_1;
    }

    public String getF57_AS_RP_2() {
        return f57_AS_RP_2;
    }

    public void setF57_AS_RP_2(String f57_AS_RP_2) {
        this.f57_AS_RP_2 = f57_AS_RP_2;
    }

    public String getF57_AS_RP_3() {
        return f57_AS_RP_3;
    }

    public void setF57_AS_RP_3(String f57_AS_RP_3) {
        this.f57_AS_RP_3 = f57_AS_RP_3;
    }

    public String getF57_AS_RA_1() {
        return f57_AS_RA_1;
    }

    public void setF57_AS_RA_1(String f57_AS_RA_1) {
        this.f57_AS_RA_1 = f57_AS_RA_1;
    }

    public String getF57_AS_NA_1() {
        return f57_AS_NA_1;
    }

    public void setF57_AS_NA_1(String f57_AS_NA_1) {
        this.f57_AS_NA_1 = f57_AS_NA_1;
    }

    public String getF57_AS_IA_1() {
        return f57_AS_IA_1;
    }

    public void setF57_AS_IA_1(String f57_AS_IA_1) {
        this.f57_AS_IA_1 = f57_AS_IA_1;
    }

    public String getF57_AS_SE_1() {
        return f57_AS_SE_1;
    }

    public void setF57_AS_SE_1(String f57_AS_SE_1) {
        this.f57_AS_SE_1 = f57_AS_SE_1;
    }

    public String getF57_AS_SE_2() {
        return f57_AS_SE_2;
    }

    public void setF57_AS_SE_2(String f57_AS_SE_2) {
        this.f57_AS_SE_2 = f57_AS_SE_2;
    }

    public String getF57_AS_SE_3() {
        return f57_AS_SE_3;
    }

    public void setF57_AS_SE_3(String f57_AS_SE_3) {
        this.f57_AS_SE_3 = f57_AS_SE_3;
    }

    public String getF57_AS_AR_1() {
        return f57_AS_AR_1;
    }

    public void setF57_AS_AR_1(String f57_AS_AR_1) {
        this.f57_AS_AR_1 = f57_AS_AR_1;
    }

    public String getF57_AS_AR_2() {
        return f57_AS_AR_2;
    }

    public void setF57_AS_AR_2(String f57_AS_AR_2) {
        this.f57_AS_AR_2 = f57_AS_AR_2;
    }

    public String getF57_AS_ID() {
        return f57_AS_ID;
    }

    public void setF57_AS_ID(String f57_AS_ID) {
        this.f57_AS_ID = f57_AS_ID;
    }

    /**
     * 获取F57_AS用法子域的数据
     *
     * @param field57Str 银联CUPS 57域值
     * @return 57域
     * @throws Exception 失败
     */
    public F57 parseF57_AS(String field57Str) throws Exception {
        F57 f57 = new F57();
        if (StringUtil.isEmptyOrNull(field57Str)) {
            return null;
        }
        //用法标识为2字节，由于只存在字母，因此用string直接判断长度，否则需要使用GB18030 byte
        if (field57Str.length() <= USE_FLAG_LEN) {
            throw new BizException(OltpRpcdEnum.PARAM_IS_EMPTY_OR_NULL);
        }
        String useFlag = field57Str.substring(0, USE_FLAG_LEN);
        if (AS.equals(useFlag)) {
            //具体数据，其格式取决于<子域tag标签>字符，长度最长不超过96个字节。加上AS标志总长不超过100,
            if (field57Str.length() > F57_MAX_LEN) {
                return null;
            }
            //AS所有内容
            String asData = field57Str.substring(USE_FLAG_LEN);
            do {
                //AS用法内子用法标签
                String tag = asData.substring(0, AS_SUBTAG_LENGTH_OFFSET_START);
                //子标签用法的内容长度为三字节，都为数字字母因此不会出现字符集问题
                int tagLen = Integer.parseInt(asData.substring(AS_SUBTAG_LENGTH_OFFSET_START, AS_SUBTAG_LENGTH_OFFSET_END));
                //单个用法的内容
                String tagValue = asData.substring(AS_SUBTAG_LENGTH_OFFSET_END, AS_SUBTAG_LENGTH_OFFSET_END + tagLen);
                switch (tag) {
                    case AS_AR:
                        //AS+AR用法 附加应答码信息
                        String rspSrc = tagValue.substring(AS_AR_1_OFFSET_START, AS_AR_1_OFFSET_END);
                        String rspCode = tagValue.substring(AS_AR_2_OFFSET_START, AS_AR_2_OFFSET_END);
                        f57.setF57_AS_AR_1(rspSrc);
                        f57.setF57_AS_AR_2(rspCode);
                        break;
                    default:
                        //其他用法只兼容 不处理 只打印
                        RgLogger rglog = RgLog.getLogger("F57");
                        rglog.info("用法<{}>:<{}>暂不支持，不解析，保证不报错兼容即可", tag, tagValue);
                        break;
                }
                //继续移动到下一个子域 （TAG 2 + LEN 3 = 5）+ （VALUE tagLen）
                asData = asData.substring(5 + tagLen);
            } while (asData.length() > 5);
            return f57;
        }
        return null;
    }

    /**
     * 字符集
     */
    public static final String GB18030 = "GB18030";
    /**
     * 用法标志 长度
     */
    public static final int USE_FLAG_LEN = 2;
    /**
     * 57域长度最大100字节
     */
    public static final int F57_MAX_LEN = 100;
    /**
     * AS组合用法标志
     */
    public static final String AS = "AS";
    /**
     * AS组合用法中子域的长度位的长度
     */
    public static final int AS_SUBTAG_LENGTH_LEN = 3;
    /**
     * AS组合用法中子域的长度位的长度 偏移开始
     */
    public static final int AS_SUBTAG_LENGTH_OFFSET_START = USE_FLAG_LEN;
    /**
     * AS组合用法中子域的长度位的长度 偏移结束
     */
    public static final int AS_SUBTAG_LENGTH_OFFSET_END = AS_SUBTAG_LENGTH_OFFSET_START + AS_SUBTAG_LENGTH_LEN;
    /**
     * AS+附加应答码信息（AR）
     */
    public static final String AS_AR = "AR";
    /**
     * AS组合用法附加应答码信息（AR） 应答码发起方an1
     */
    public static final int AS_AR_1_LEN = 1;
    /**
     * AS组合用法附加应答码信息（AR） 应答码发起方an1 相对于AR用法的偏移开始
     */
    public static final int AS_AR_1_OFFSET_START = 0;
    /**
     * AS组合用法附加应答码信息（AR） 应答码发起方an1 相对于AR用法的偏移结束
     */
    public static final int AS_AR_1_OFFSET_END = AS_AR_1_OFFSET_START + AS_AR_1_LEN;
    /**
     * AS组合用法附加应答码信息（AR） 附加应答信息取值an2
     */
    public static final int AS_AR_2_LEN = 2;
    /**
     * AS组合用法附加应答码信息（AR） 附加应答信息取值an2 相对于AR用法的偏移开始
     */
    public static final int AS_AR_2_OFFSET_START = AS_AR_1_OFFSET_END;
    /**
     * AS组合用法附加应答码信息（AR） 附加应答信息取值an2 相对于AR用法的偏移结束
     */
    public static final int AS_AR_2_OFFSET_END = AS_AR_2_OFFSET_START + AS_AR_2_LEN;
}